<?php

namespace Dls\Entity\V0\Grid\Exporters;

use Dls\Entity\V0\Grid\Column;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;

class CsvExporter extends AbstractExporter
{
    /**
     * 列对象集合
     *
     * @var Collection  null
     */
    private $columns = null;

    /**
     * {@inheritdoc}
     */
    public function export()
    {
        $this->columns = $this->filter();

        $filename = $this->getTable().'.csv';
        $headers = [
            'Content-Encoding'    => 'UTF-8',
            'Content-Type'        => 'text/csv;charset=UTF-8',
            'Content-Disposition' => "attachment; filename=\"$filename\"",
        ];
        response()->stream(function () {
            $handle = fopen('php://output', 'w');
            fwrite($handle, chr(0xEF).chr(0xBB).chr(0xBF));
            // Add CSV headers
            fputcsv($handle, $this->getHeaderRowFromRecords());
            $this->chunk(function ($records) use ($handle) {
                foreach ($records as $record) {
                    fputcsv($handle, $this->getFormattedRecord($record));
                }
            });
            // Close the output stream
            fclose($handle);
        }, 200, $headers)->send();
        exit;
    }
    /**
     * @param Collection $records
     *
     * @return array
     */
    public function getHeaderRowFromRecords(): array
    {
        return $this->columns->map(function (Column $column) {
                return $column->getLabel();
            })->toArray();
    }
    /**
     * @param array $record
     *
     * @return array
     */
    public function getFormattedRecord(array $record)
    {
        return $this->columns->mapWithKeys(function (Column $column) use ($record) {
            return [$column->getAlias() => $record[$column->getAlias()]];
        })->toArray();
    }

    private function filter()
    {
        return $this->grid->columns()
            ->filter(function (Column $column) {
                return $column->getLabel() == strip_tags($column->getLabel());
            })->filter(function (Column $column) {
                return !$column->isHide();
            });
    }

}